#include<bits/stdc++.h>
using namespace std;

long long n,m,len,lv,s=0,lvv;
int t;
int car[100010][7];
long long cl[100010];
long long l[100010];

void check1(){
	bool f=false;long long s2=m;
	for(int i=1;i<=n;i++){
		f=false;
		if(car[i][2]<=lv)continue;

		// if(upper_bound(l+1,l+m+1,car[i][1])-l<m){
		// 	cl[s]=upper_bound(l+1,l+m+1,car[i][1])-l;f=true;
		// }else{
		if(l[m]>=car[i][1]){
			cl[s]=m;f=true;
			}
		// }
		if(f){
			s++;
		}

	// }
	// sort(cl,cl+s);
	if(s==0){
		s2=m;
	}else{
		s2=m-1;
	}
	}
	printf("%lld %lld\n",s,s2);
	s=0;

}

void check2(){
	bool f=false;long long s2=m;long long d=0;
	for(int i=1;i<=n;i++){
		f=false;
		
		d=lvv-car[i][2]*car[i][2];
		if(d>0){
			if(d%2*car[i][3]){
				d/=2*car[i][3];
				d+=1;
				if(l[m]>=car[i][1]+d){
					cl[s]=m;f=true;s++;
				}
			}else{
				d/=2*car[i][3];
			
				if(l[m]>car[i][1]+d){
					cl[s]=m;f=true;s++;
				}
			}
		}else if(d<0){
			if(l[m]>=car[i][1]){
			cl[s]=m;f=true;s++;
			}
		}else{
			if(l[m]>car[i][1]){
			cl[s]=m;f=true;s++;
			}
		}
		

		

		// if(upper_bound(l+1,l+m+1,car[i][1])-l<m){
		// 	cl[s]=upper_bound(l+1,l+m+1,car[i][1])-l;f=true;
		// }else{
		// if(l[m]>=car[i][1]){
		// 	cl[s]=m;f=true;
		// 	}
		// }


	// }
	// sort(cl,cl+s);
		if(s==0){
			s2=m;
		}else{
			s2=m-1;
		}
	}
	printf("%lld %lld\n",s,s2);
	s=0;

}



void detect(){
	scanf("%lld%lld%lld%lld",&n,&m,&len,&lv);
	lvv=lv*lv;
	memset(car,0,sizeof(car));
	for(int i=1;i<=n;i++){
		scanf("%d%d%d",&car[i][1],&car[i][2],&car[i][3]);
	}

	for(int i=1;i<=m;i++){
		scanf("%lld",&l[i]);
	}
	if(car[1][3]==0){
		check1();
	}
	if(car[1][3]>0){
		check2();
	}
	



}


int main(){
	freopen("detect.in","r",stdin);
	freopen("detect.out","w",stdout);
	scanf("%d",&t);
	for(int i=1;i<=t;i++){
		detect();
	}


	return 0;
}
